package com.zyf.chapter01.practice.v3;

import com.zyf.chapter01.practice.v3.util.AysncEventBus;
import com.zyf.chapter01.practice.v3.util.EventBus;
import com.zyf.chapter01.practice.v3.util.EventListener;
import com.zyf.chapter01.principle.DRY.utils.StringUtils;
import com.zyf.chapter01.principle.practice.MetricsStorage;
import com.zyf.chapter01.principle.practice.RedisMetricsStorage;
import com.zyf.chapter01.principle.practice.RequestInfo;

import java.util.concurrent.Executors;

/**
 * 提供 API，来采集接口请求的原始数据
 * 职责相对比较单一，基于接口而非实现编程，可以在不修改代码的情况下，灵活替换
 * 1.新增易用性 封装默认依赖 <br />
 * 2.考虑性能，
 *      对于低延迟的我那天，我们可以使用事件总线，异步存储
 *      对于框架本身内存消耗问题
 * @author yifeng
 * @since v3
 */
public class MetricsCollector {
    // 基于接口而非实现编程
    private MetricsStorage metricsStorage;
    private EventBus eventBus;
    // 兼容代码的易用性，新增一个封装了默认依赖的构造函数
    public MetricsCollector() {
        this(new RedisMetricsStorage());
    }
    // 兼容灵活性和代码的可测试性，这个构造函数继续保留
    public MetricsCollector(MetricsStorage metricsStorage) {
        this.metricsStorage = metricsStorage;
    }

    public MetricsCollector(MetricsStorage metricsStorage, int threadNumToSaveDate) {
        this.metricsStorage = metricsStorage;
        this.eventBus = new AysncEventBus(Executors.newFixedThreadPool(threadNumToSaveDate));
        this.eventBus.register(new EventListener());

    }
    public void recordRequest(RequestInfo requestInfo) {
        if (requestInfo == null || StringUtils.isBlank(requestInfo.getApiName())) {
            return;
        }
        eventBus.post(requestInfo);

        metricsStorage.saveRequestInfo(requestInfo);
    }
}
